<template>
  <el-table :data="PermisstionArr" style="width: 100%; margin-bottom: 20px" row-key="pid" border>
    <el-table-column align="center" width="200" label="菜单名称" prop="permissiondes"></el-table-column>
    <el-table-column align="center" width="60" label="图标" prop="icon">
      <template #default="scope">
        <svg-icon :icon-class="scope.row.icon"/>
      </template>
    </el-table-column>
    <el-table-column align="center" width="60" label="排序" prop="ordernum"></el-table-column>
    <el-table-column align="center" label="权限标识" prop="permissionval"></el-table-column>
    <el-table-column align="center" label="路由地址" prop="path"></el-table-column>
    <el-table-column align="center" label="组件路径" prop="component"></el-table-column>
    <el-table-column align="center" width="300px" label="操作">
      <template #default="scope">
        <el-button
            type="primary"
            v-hasPermi="['menu_add']"
            icon="Plus"
            size="small"
            :disabled="scope.row.level == 4 ? true : false"
            @click="handleAdd(scope.row)"
        >
          {{ scope.row.level == 3 ? '添加功能' : '添加' }}
        </el-button>
        <el-button
            type="primary"
            v-hasPermi="['menu_update']"
            icon="Edit"
            size="small"
            :disabled="scope.row.level == 1 ? true : false"
            @click="handleUpdate(scope.row)"
        >
          修改
        </el-button>
        <el-popconfirm :title="`你确定要删除${scope.row.permissiondes}?`" width="260px"
                       @confirm="removeMenu(scope.row.pid)">
          <template #reference>
            <el-button v-hasPermi="['menu_delete']"
                       type="primary" size="small" :disabled="scope.row.level == 1 ? true : false">删除
            </el-button>
          </template>
        </el-popconfirm>
      </template>
      <!-- row:即为已有的菜单对象|按钮的对象的数据 -->
    </el-table-column>
  </el-table>

  <!-- 对话框组件:添加或者更新已有的菜单的数据结构 -->
  <el-dialog v-model="dialogVisible" :title="menuData.pid ? '更新菜单' : '添加菜单'">
    <!-- 表单组件:收集新增与已有的菜单的数据 -->
    <el-form :rules="rules" ref="form" :model="menuData" label-width="100px">
      <el-row>
        <el-col :span="24">
          <el-form-item label="上级菜单">
            <el-tree-select
                v-model="menuData.parentid"
                :data="menuOptions"
                :props="{ value: 'pid', label: 'permissiondes', children: 'children' }"
                value-key="menuId"
                placeholder="选择上级菜单"
                check-strictly
            />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="菜单类型" prop="type">
            <el-radio-group v-model="menuData.type">
              <el-radio label="M">目录</el-radio>
              <el-radio label="C">菜单</el-radio>
              <el-radio label="F">按钮</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="24" v-if="menuData.type != 'F'">
          <el-form-item label="菜单图标" prop="icon">
            <el-popover
                v-model:visible="showChooseIcon"
                placement="bottom-start"
                :width="540"
                trigger="click"
                @show="showSelectIcon"
                @blur="hideSelectIcon"
                @mouseenter="showSelectIcon"
                @mouseleave="hideSelectIcon"
            >
              <template #reference>
                <el-input v-model="menuData.icon"
                          placeholder="点击选择图标"
                          v-click-outside="hideSelectIcon"
                          @focus="showSelectIcon"
                          readonly>
                  <template #prefix>
                    <svg-icon v-if="menuData.icon"
                              :icon-class="menuData.icon"
                              class="el-input__icon"
                              style="height: 32px;width: 16px;"/>
                    <el-icon v-else style="height: 32px;width: 16px;">
                      <search/>
                    </el-icon>
                  </template>
                </el-input>
              </template>
              <icon-select ref="iconSelectRef"
                           :active-icon="menuData.icon"
                           @selected="selected"
                           @mouseenter="showSelectIcon"
                           @mouseleave="hideSelectIcon"
              />
            </el-popover>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="菜单名称" prop="permissiondes">
            <el-input v-model="menuData.permissiondes" placeholder="请输入菜单名称"/>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="显示排序" prop="ordernum">
            <el-input-number v-model="menuData.ordernum" controls-position="right" :min="0"/>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="menuData.type != 'F'">
          <el-form-item prop="path">
            <template #label>
                        <span>
                           <el-tooltip content="访问的路由地址，如：`user`，如外网地址需内链访问则以`http(s)://`开头"
                                       placement="top">
                              <el-icon><question-filled/></el-icon>
                           </el-tooltip>
                           路由地址
                        </span>
            </template>
            <el-input v-model="menuData.path" placeholder="请输入路由地址"/>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="menuData.type == 'C'">
          <el-form-item prop="component">
            <template #label>
                        <span>
                           <el-tooltip content="访问的组件路径，如：`system/user/index`，默认在`views`目录下"
                                       placement="top">
                              <el-icon><question-filled/></el-icon>
                           </el-tooltip>
                           组件路径
                        </span>
            </template>
            <el-input v-model="menuData.component" placeholder="请输入组件路径"/>
          </el-form-item>
        </el-col>
        <el-col :span="12" v-if="menuData.type != 'M'">
          <el-form-item prop="permissionval">
            <el-input v-model="menuData.permissionval" placeholder="请输入权限标识" maxlength="100"/>
            <template #label>
                        <span>
                           <el-tooltip
                               content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasPermi('system:user:list')`)"
                               placement="top">
                              <el-icon><question-filled/></el-icon>
                           </el-tooltip>
                           权限字符
                        </span>
            </template>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>

    <template #footer>
            <span class="dialog-footer">
                <el-button @click="dialogVisible = false">取消</el-button>
                <el-button type="primary" @click="save">
                    确定
                </el-button>
            </span>
    </template>
  </el-dialog>
</template>

<script setup name="Menu">
import {ref, onMounted} from "vue";
import {reqAllPermisstion, reqAddOrUpdateMenu, reqRemoveMenu} from '@/api/acl/menu';
import IconSelect from "@/components/IconSelect";
import {ClickOutside as vClickOutside, ElMessage} from 'element-plus'
//获取form组件实例
const form = ref();
const showChooseIcon = ref(false)
const iconSelectRef = ref(null)
//存储菜单的数据
const PermisstionArr = ref([]);
//下拉菜单数据
const menuOptions = ref([]);
//控制对话框的显示与隐藏
const dialogVisible = ref(false);
//携带的参数
const menuData = ref({
  permissionval: "",
  permissiondes: "",
  ordernum: 0,
  path: "",
  component: "",
  type: "",
  icon: "",
  parentid: 0,
})
//获取菜单数据的方法
const getHasPermisstion = async () => {
  let result = await reqAllPermisstion();
  if (result.code == 200) {
    PermisstionArr.value = result.data;
    //制空
    menuOptions.value = []
    const menu = {pid: 0, permissiondes: "主类目", children: []};
    menu.children = result.data;
    menuOptions.value.push(menu);
  }
}
//添加菜单按钮的回调
const handleAdd = (row) => {
  //清空数据
  Object.assign(menuData.value, {
    permissionval: "",
    permissiondes: "",
    ordernum: 0,
    path: "",
    component: "",
    type: "",
    icon: "",
    pid: 0,
  })
  //对话框显示出来
  dialogVisible.value = true;
  //收集新增的菜单的level数值
  menuData.value.level = row.level + 1;
  //给谁新增子菜单
  menuData.value.pid = (row.id);

}
/** 展示下拉图标 */
const showSelectIcon = () => {
  iconSelectRef.value.reset()
  if (menuData.value.icon) {
    showChooseIcon.value = true;
  }
}
/** 选择图标 */
const selected = (name) => {
  menuData.value.icon = name;
  showChooseIcon.value = false;
}
/** 图标外层点击隐藏下拉列表 */
const hideSelectIcon = (event) => {
  let elemData =
      event.relatedTarget ||
      event.srcElement ||
      event.target ||
      event.currentTarget;
  let {className} = elemData;
  console.log("elem", className)
  if (className !== 'el-input__inner') {
    showChooseIcon.value = false;
  }
}

//编辑已有的菜单
const handleUpdate = (row) => {
  dialogVisible.value = true;
  //点击修改按钮:收集已有的菜单的数据进行更新
  Object.assign(menuData.value, row);
}

//确定按钮的回调
const save = async () => {
  //表单校验结果,结果通过在发请求、结果没有通过不应该在发生请求
  await form.value.validate();
  //发请求:新增子菜单|更新某一个已有的菜单的数据
  let result = await reqAddOrUpdateMenu(menuData.value);
  if (result.code == 200) {
    //对话框隐藏
    dialogVisible.value = false;
    //提示信息
    ElMessage({type: 'success', message: menuData.value.id ? '更新成功' : '添加成功'})
    //再次获取全部最新的菜单的数据
    getHasPermisstion();
  }
}

//删除按钮回调
const removeMenu = async (id) => {
  let result = await reqRemoveMenu(id);
  if (result.code == 200) {
    ElMessage({type: 'success', message: '删除成功'});
    getHasPermisstion();

  }
}

const rules = {
  permissiondes: [{required: true, message: "菜单名称不能为空", trigger: "blur"}],
  ordernum: [{required: true, message: "菜单顺序不能为空", trigger: "blur"}],
  path: [{required: true, message: "路由地址不能为空", trigger: "blur"}],
  permissionval: [{required: true, message: "权限字符不能为空", trigger: "blur"}],
  component: [{required: true, message: "组件路径不能为空", trigger: "blur"}]
}
//组件挂载完毕
onMounted(() => {
  getHasPermisstion();
});
</script>

<style scoped></style>
